class_name
可以變更關聯的類別名稱,例如以下新增了paid_attendees關聯,和另一個has_many :attendees都關聯到同一個attendees table:
class Event < ApplicationRecord
has_many :attendees
has_many :paid_attendees, :class_name => "Attendee"
#...
end
## foreign_key
可以變更Foreign Key的欄位名稱,例如改成paid_user_id:
class Event < ApplicationRecord
belongs_to :paid_user, :class_name => "User", :foreign_key => "paid_user_id"
#...
end
## scope
在第二個參數傳入匿名函式,可以設定關聯的範圍條件,例如:
class Event < ApplicationRecord
has_many :attendees
has_many :paid_attendees, -> { where(:status => "paid") }, :class_name => 'Attendee'
#...
end
這個語法跟我們之前學過的Arel串接寫法是一樣的,所以可以繼續串接加上排序等其他條件:
class Event < ApplicationRecord
has_many :attendees
has_many :paid_attendees, -> { where(:status => "paid").order("id DESC") }, :class_name => 'Attendee'
#...
end
可以設定當物件刪除時,怎麼處理依賴它的資料,例如:
class Event < ApplicationRecord
has_many :attendees, :dependent => :destroy
end
其中:dependent可以設定有幾種不同的處理方式,例如:
:destroy 把依賴的attendees也一併刪除,並且執行Attendee的destroy回呼
:delete 把依賴的attendees也一併刪除,但不執行Attendee的destroy回呼
:nullify 不會幫忙刪除attendees,但會把attendees的外部鍵event_id都設成NULL
:restrict_with_exception 如果有任何依賴的attendees資料,則連event都不允許刪除。執行刪除時會丟出錯誤例外ActiveRecord::DeleteRestrictionError。
:restrict_with_error 不允許刪除。執行刪除時會回傳false,在@event.errors中會留有錯誤訊息。
如果沒有設定:dependent的話,就不會特別去處理。
要不要執行attendee的刪除回呼差在執行效率,如果需要回呼的話,必須一筆筆把attendee讀取出來變成attendee物件,然後呼叫它的destroy。如果用:delete的話,只需要一個SQL語句就可以刪除全部attendee了。
透過關聯來建立另一個關聯集合,用於建立多對多的關係。
class Event < ApplicationRecord
has_many :event_groupships
has_many :groups, :through => :event_groupships
end
source
搭配through設定使用,當關聯的名稱不一致的時候,需要加上source指名是哪一種物件。
class Event < ApplicationRecord
has_many :event_groupships
has_many :classifications, :through => :event_groupships, :source => :group
end
多了兩個方法可以新增關聯物件:
build_{association_name}
create_{association_name}
例如:
e = Event.first
e.build_location
class_name、dependent、scope條件等設定,都和has_many一樣